{
Group commands for execution
TLDR
Isolate variable names
Brace expand sequences
Check if variable is set before returning text
Set default values in case variable is unset
Return variable length in characters
Return a string slice
Recursively expand a variable
Group command output together
SYNOPSIS
{ list-of-commands; }
Note: The semicolon (;) or a newline before the closing } is mandatory when } is on the same line as the last command within the group. A space is required after { and before }.
PARAMETERS
list-of-commands
One or more commands, separated by semicolons (;) or newlines, that are executed sequentially as a single logical unit within the current shell environment. Variables and environment changes made here persist after the group completes.
DESCRIPTION
The { character is a special shell reserved word in Bourne-like shells such as Bash, Zsh, and Ksh. It marks the beginning of a command group, also known as a brace group or compound command. When used in conjunction with its closing counterpart, }, it allows multiple commands to be treated as a single unit.
A key characteristic of a command group formed with { ... } is that the commands inside are executed in the current shell environment. This means that any variable assignments, directory changes (cd), or function definitions made within the group will persist after the group completes. This behavior contrasts with commands enclosed in parentheses ( ... ), which execute in a subshell, where such changes are temporary and do not affect the parent shell.
Command groups are frequently employed in shell scripting with control flow statements like if, while, for, and case to define the blocks of code to be executed conditionally or iteratively. They can also be used to apply redirections to a series of commands collectively. For example, { command1; command2; } > output.txt redirects the output of both command1 and command2 to output.txt. The { must be separated from the first command by whitespace, and a semicolon or newline must precede the closing } if it's on the same line.
CAVEATS
The { character must be followed by whitespace. A closing } is mandatory. If the closing } is on the same line as the last command, a semicolon (;) or a newline must precede it. Failing to separate {, } or placing the semicolon can lead to syntax errors. Changes to the shell environment (e.g., variables, current directory) within a brace group persist, which might be an unexpected behavior if one expects subshell isolation.
<B>BRACE GROUP VS. SUBSHELL</B>
While both { ... } (a brace group) and ( ... ) (a subshell) can group commands, their fundamental difference lies in their execution environment. Commands within a brace group run in the current shell, meaning any changes to shell options, variables, or the working directory are permanent and affect the rest of the script or interactive session. In contrast, commands within a subshell run in a new, independent process. Any changes made within the subshell are local to that subshell and are discarded upon its completion, leaving the parent shell unaffected. For example:
{ cd /tmp; echo $PWD; } (changes directory permanently)
( cd /tmp; echo $PWD; ) (changes directory only for the subshell)
<B>NOT FOR BRACE EXPANSION</B>
It is important not to confuse the command grouping use of { with brace expansion (e.g., {a,b,c} or {1..5}). Brace expansion is a mechanism that generates new strings from a pattern, typically used for file naming or generating lists (e.g., touch file{1..3}.txt expands to touch file1.txt file2.txt file3.txt). While both use braces, their functionality and context of use are entirely different. Command grouping requires { to be a reserved word, separated by whitespace, and part of a compound command, whereas brace expansion is a form of word splitting/generation.
HISTORY
The concept of command grouping using braces ({ ... }) has been a fundamental part of the Bourne shell (sh) syntax since its inception in the late 1970s. It was designed to provide a way to execute a block of commands within the current shell's context, making it distinct from subshells. This feature was inherited and maintained by all POSIX-compliant shells, including Bash, Ksh, and Zsh, ensuring its widespread and consistent usage in shell scripting for decades.